package javaSePrictice;

/**
 *根据 逆波兰表示法，求表达式的值。
 * 有效的运算符包括 +, -, *, / 。每个运算对象可以是整数，也可以是另一个逆波兰表达式。
 * 示例 1：
 * 输入: ["2", "1", "+", "3", "*"]
 * 输出: 9
 * 解释: 该算式转化为常见的中缀算术表达式为：((2 + 1) * 3) = 9
 * 示例 2：
 * 输入: ["4", "13", "5", "/", "+"]
 * 输出: 6
 * 解释: 该算式转化为常见的中缀算术表达式为：(4 + (13 / 5)) = 6
 * 示例 3：
 * 输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
 * 输出: 22
 * 解释:
 * 该算式转化为常见的中缀算术表达式为：
 *   ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
 * = ((10 * (6 / (12 * -11))) + 17) + 5
 * = ((10 * (6 / -132)) + 17) + 5
 * = ((10 * 0) + 17) + 5
 * = (0 + 17) + 5
 * = 17 + 5
 * = 22
 *
 * 逆波兰表达式：
 * 逆波兰表达式是一种后缀表达式，所谓后缀就是指算符写在后面。
 * 平常使用的算式则是一种中缀表达式，如 ( 1 + 2 ) * ( 3 + 4 ) 。
 * 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
 * 逆波兰表达式主要有以下两个优点：
 * 去掉括号后表达式无歧义，上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
 * 适合用栈操作运算：遇到数字则入栈；遇到算符则取出栈顶两个数字进行计算，并将结果压入栈中。
 *
 */


public class 逆波兰表达式求值问题 {
    public static void main(String[] args) {
        String[] tokens={"2", "1", "+", "3", "*"};
        int result=evalRPN(tokens);
        System.out.println(result);
    }
    public  static  int evalRPN(String[] tokens) {
        int[] arr=new int[tokens.length]; //定义一个数组用来存放字符数组内容
        int i=0;
        for(String token:tokens){
            switch (token){
                case "+":
                    arr[i-2]+=arr[--i];  //遇到加法运算符就前两个相加
                    break;
                case "-":
                    arr[i-2] -=arr[--i]; //遇到减法运算符就前两个相减
                    break;
                case "*":
                    arr[i-2] *=arr[--i]; //遇到乘法运算符就前两个相乘
                    break;
                case "/":
                    arr[i-2] /=arr[--i]; //遇到除法运算符就前两个相除
                    break;
                default:
                    arr[i++]=Integer.valueOf(token); //若没有遇到运算符就把字符串存放进数组
                    break;
            }
        }
        return arr[0]; //最后取数组第一个元素的值就是计算后的值
    }
}
